home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992…ugust: Hack to the Future / ADC Developer CD (1992-08) (''Hack To The Future'')_iso / Dev.CD 199208.iso / Technical Documentation / DTS Sample Code / Snippets / OS / KillEveryOneButMe / KillEveryOneButMe.c next >
Encoding:
C/C++ Source or Header  |  1992-07-15  |  20.1 KB  |  554 lines  |  [TEXT/MPS ]

  1. /* KillEveryBodyButMe.c */
  2. /* Some folks want to kill all the other applications running on a machine */
  3. /* for demos, school situations, kiosks, etc. */
  4. /* with System 7, it's easy, just use the Process Manager and AppleEvents. */
  5. /* This thing shows you how. */
  6. /* PLEASE don't abuse this.  System 7 gives the user full-time multiFinder, and they */
  7. /* like it, our System Software team worked very hard to make this */
  8. /* happen.  ONLY do this in very special circumstances, or you're taking */
  9. /* power away from the user and weakening the strength of the Mac. */
  10. /* Written  by C.K. Haun <TR> */
  11. /* Apple Developer Tech Support */
  12.  
  13. /* Of course, Copyright 1991, Apple Computer Inc. */
  14. #include <Types.h>
  15. #include <memory.h>
  16. #include <Packages.h>
  17. #include <Errors.h>
  18. #include <quickdraw.h>
  19. #include <fonts.h>
  20. #include <dialogs.h>
  21. #include <windows.h>
  22. #include <menus.h>
  23. #include <events.h>
  24. #include <OSEvents.h>
  25. #include <Desk.h>
  26. #include <diskinit.h>
  27. #include <OSUtils.h>
  28. #include <resources.h>
  29. #include <toolutils.h>
  30. #include <AppleEvents.h>
  31. #include <EPPC.h>
  32. #include <GestaltEqu.h>
  33. #include <PPCToolbox.h> 
  34. #include <Processes.h>
  35. #include <Balloons.h>
  36. /* prototypes */
  37. void InitalizeApp(void);
  38. void DoDiskEvents(long dinfo);                              /* hi word is error code, lo word is drive number */
  39. void DrawMain(WindowPtr drawIt);
  40. Boolean DoSelected(long val);
  41.  
  42. void InitAEStuff(void);
  43. void DoHighLevel(EventRecord *AERecord);
  44. void DoDaCall(MenuHandle themenu, long theit);
  45. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  46. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  47. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  48. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn);
  49. void SampleHelpDialog(void);
  50. void KillEveryBody(void);
  51. /* one external */
  52. extern void _DataInit();                                    /* this is the C initialization code */
  53.  
  54. #define kMBarID 128
  55. #define kAppleMenu 128
  56. #define kFileMenu 129
  57. #define kEditMenu 130
  58. #define kToolsMenu 131
  59. #define kResumeMask             1       /* bit of message field for resume vs. suspend */
  60. #define kSampHelp 129
  61. #define kAboutBox 128
  62. #define kHelpString 128
  63. #define kNewItem 1
  64. #define kOpenItem 2
  65. #define kCloseItem 3
  66. #define kSaveItem 4
  67. #define kSaveAsItem 5
  68. #define kFileBlank1 6
  69. #define kPageSetupItem 7
  70. #define kPrintItem 8
  71. #define kFileBlank2 9
  72. #define kQuitItem 10
  73. #define kBadSystem 130
  74. #define kTitle 129
  75. struct AEinstalls {
  76.     AEEventClass theClass;
  77.     AEEventID theEvent;
  78.     EventHandlerProcPtr theProc;
  79. };
  80. typedef struct AEinstalls AEinstalls;
  81.  
  82. Handle gMymenu;                                             /* my menu bar handle */
  83. MenuHandle gAppleMenuHandle, gFileMenuHandle, gEditMenuHandle, gToolMenuHandle;
  84. Boolean gQuit, gInBackground;
  85. EventRecord gERecord;
  86. AEDesc gTheAddress;
  87. WindowPtr myWindow;
  88. ProcessSerialNumber gOurSN;
  89. short gHelpItem;
  90.  
  91. #pragma segment Main
  92. main()
  93. {
  94.     WindowPtr twindow;
  95.     UnloadSeg((Ptr)_DataInit);                              /* throw out setup code */
  96.     InitalizeApp();
  97.     UnloadSeg((Ptr)InitalizeApp);                           /* get rid of my initialization code */
  98.     do {
  99.         WaitNextEvent(everyEvent, &gERecord, 30, nil);
  100.         switch (gERecord.what) {
  101.             
  102.             case nullEvent:
  103.                 /* no nul processing in this sample */
  104.                 break;
  105.             case updateEvt:
  106.                 DrawMain((WindowPtr)gERecord.message);      /* draw whatever window needs an update */
  107.                 break;
  108.             case mouseDown:
  109.                 /* first see where the hit was */
  110.                 switch (FindWindow(gERecord.where, &twindow)) {
  111.                     
  112.                     case inDesk:                            /* if they hit in desk, then the process manager */
  113.                         break;                              /* will switch us out, we don't need to do anything */
  114.                     case inMenuBar:
  115.                         DoSelected(MenuSelect(gERecord.where));
  116.                         break;
  117.                         
  118.                     case inSysWindow:
  119.                         /* pass to the system */
  120.                         SystemClick(&gERecord, twindow);
  121.                         break;
  122.                     case inContent:
  123.                         /* Handle content and control clicks here */
  124.                         break;
  125.                     case inDrag:
  126.                         if (twindow == FrontWindow())
  127.                             DragWindow(twindow, gERecord.where, &qd.screenBits.bounds);
  128.                         break;
  129.                     case inGrow:
  130.                         /* Call GrowWindow here if you have a grow box */
  131.                         break;
  132.                     case inGoAway:
  133.                         /* Click in Close box */
  134.                         break;
  135.                         
  136.                 }
  137.             case mouseUp:
  138.                 /* don't care */
  139.                 break;
  140.                 /* same action for key or auto key */
  141.             case keyDown:
  142.             case autoKey:
  143.                 if (gERecord.modifiers & cmdKey)
  144.                     DoSelected(MenuKey(gERecord.message & charCodeMask));
  145.                 break;
  146.             case keyUp:
  147.                 /* don't care */
  148.                 break;
  149.             case diskEvt:
  150.                 /* I don't do anything special for disk events, this just passes them */
  151.                 /* to a function that checks for an error on the mount */
  152.                 DoDiskEvents(gERecord.message);
  153.                 break;
  154.             case activateEvt:
  155.                 if (gERecord.modifiers & activeFlag)
  156.                     DrawMain((WindowPtr)gERecord.message);
  157.                 break;
  158.             case networkEvt:
  159.                 /* don't care */
  160.                 break;
  161.             case driverEvt:
  162.                 /* don't care */
  163.                 break;
  164.             case app4Evt:
  165.                 switch ((gERecord.message >> 24) & 0x0FF) {     /* high byte of message */
  166.                     case suspendResumeMessage:              /* suspend/resume is also an activate/deactivate */
  167.                         gInBackground = (gERecord.message & kResumeMask) == 0;
  168.                         break;
  169.                 }
  170.                 break;
  171.             default:
  172.                 break;
  173.                 /* This dispatches high level events (AppleEvents, for example) */
  174.                 /* to our dispatch routine.  This is NEW in the event loop for */
  175.                 /* System 7 */
  176.             case kHighLevelEvent:
  177.                 DoHighLevel(&gERecord);
  178.                 break;
  179.                 
  180.         }
  181.     }
  182.             while (gQuit != true);
  183.     
  184. }
  185.  
  186. /* DoDaCall opens the requested DA.  It's here as a seperate routine if you'd */
  187. /* like to perform some action or just know when a DA is opened in your */
  188. /* layer.  Can be handy to track memory problems when a DA is opened */
  189. /* with an Option-open */
  190. void DoDaCall(MenuHandle themenu, long theit)
  191. {
  192.     long qq;
  193.     char DAname[255];
  194.     GetItem(themenu, theit, &DAname);
  195.     qq = OpenDeskAcc(DAname);
  196. }
  197.  
  198. /* end DoDaCall */
  199.  
  200. /* DoDiskEvents just checks the error code from the disk mount, */
  201. /* and puts up the 'Format' dialog (through DIBadMount) if need be */
  202. /* You can do much more here if you care about what disks are */
  203. /* in the drive */
  204. void DoDiskEvents(long dinfo)                               /* hi word is error code, lo word is drive number */
  205. {
  206.     short hival, loval, tommy;
  207.     Point fredpoint =  {
  208.         40, 40
  209.     };
  210.     hival = HiWord(dinfo);
  211.     loval = LoWord(dinfo);
  212.     if (hival != noErr)                                     /* something happened */ {
  213.         tommy = DIBadMount(fredpoint, dinfo);
  214.     }
  215. }
  216.  
  217. /* draws my window.  Pretty simple */
  218. void DrawMain(WindowPtr drawIt)
  219. {
  220.     short vPos, hPos;
  221.     short incre = 20;
  222.     short oldFace;
  223.     ProcessInfoRec infoRec;
  224.     StringHandle theString;
  225.     OSErr myErr;
  226.     Str31 processName;
  227.     FSSpec procSpec;
  228.     ProcessSerialNumber processSN;
  229.     processSN.lowLongOfPSN = kNoProcess;
  230.     processSN.highLongOfPSN = kNoProcess;
  231.     vPos = 15;
  232.     hPos = 20;
  233.     BeginUpdate(drawIt);
  234.     SetPort(drawIt);
  235.     EraseRect(&drawIt->portRect);
  236.     MoveTo(hPos, vPos);
  237.     theString = GetString(kTitle);
  238.     HLock((Handle)theString);
  239.     oldFace = drawIt->txFace;
  240.     TextFace(bold);
  241.     DrawString((ConstStr255Param)*theString);
  242.     TextFace(oldFace);
  243.     ReleaseResource((Handle)theString);
  244.     vPos += incre;
  245.     do {
  246.         myErr = GetNextProcess(&processSN);
  247.         
  248.         infoRec.processInfoLength = sizeof(ProcessInfoRec);
  249.         infoRec.processName = &processName;
  250.         infoRec.processAppSpec = &procSpec;
  251.         myErr = GetProcessInformation(&processSN, &infoRec);
  252.         if (!myErr) {
  253.             MoveTo(hPos, vPos);
  254.             DrawString(infoRec.processName);
  255.             vPos += incre;
  256.         }
  257.     }
  258.             while (myErr == noErr);
  259.     
  260.     EndUpdate(drawIt);
  261. }
  262.  
  263. /* my menu action taker.  It returns a Boolean which I usually ignore, but it */
  264. /* mught be handy someday */
  265. Boolean DoSelected(long val)
  266. {
  267.     short loval, hival;
  268.     Boolean returnVal = false;
  269.     loval = LoWord(val);
  270.     hival = HiWord(val);
  271.     
  272.     switch (hival) {                                        /* switch off the menu number selected */
  273.         case kAppleMenu:                                    /* Apple menu */
  274.             if (loval != 1) {                               /* if this was not About, it's a DA */
  275.                 DoDaCall(gAppleMenuHandle, loval);
  276.             } else {
  277.                 Alert(kAboutBox, nil);                      /* do about box */
  278.             }
  279.             returnVal = true;
  280.             break;
  281.         case kFileMenu:                                     /* File menu */
  282.             switch (loval) {
  283.                 case kQuitItem:
  284.                     gQuit = true;                           /* only  item */
  285.                     returnVal = true;
  286.                     break;
  287.                 default:
  288.                     break;
  289.             }
  290.             break;
  291.         case kEditMenu:
  292.             /* edit menu junk */
  293.             /* don't care */
  294.             break;
  295.         case kToolsMenu:
  296.             /* add all your test stuff here */
  297.             /* only one item, kill stuff */
  298.             KillEveryBody();
  299.             break;
  300.         case kHMHelpMenuID:                                 /* Defined in Balloons.h */
  301.             /* I only care about this item.  If anything else is returned here, I don't know what */
  302.             /* it is, so I leave it alone.  Remember, the Help Manager chapter says that */
  303.             /* Apple reserves the right to add and change things in the Help menu */
  304.             if (loval == gHelpItem)
  305.                 SampleHelpDialog();
  306.             break;
  307.             
  308.     }
  309.     HiliteMenu(0);
  310.     return(returnVal);
  311. }
  312.  
  313. /* InitAEStuff installs my appleevent handlers */
  314. void InitAEStuff(void)
  315. {
  316.     static AEinstalls HandlersToInstall[] =  {
  317.         {
  318.             kCoreEventClass, kAEOpenApplication, AEOpenHandler
  319.         },  {
  320.             kCoreEventClass, kAEOpenDocuments, AEOpenDocHandler
  321.         },  {
  322.             kCoreEventClass, kAEQuitApplication, AEQuitHandler
  323.         },  {
  324.             kCoreEventClass, kAEPrintDocuments, AEPrintHandler
  325.         }, 
  326.         /* The above are the four required AppleEvents. */
  327.         
  328.     };
  329.     
  330.     OSErr aevtErr = noErr;
  331.     long aLong = 0;
  332.     Boolean gHasAppleEvents = false;
  333.     /* Check this machine for AppleEvents.  If they are not here (ie not 7.0)
  334.     *   then we exit */
  335.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &aLong) == noErr);
  336.     /* The following series of calls installs all our AppleEvent Handlers.
  337.     *   These handlers are added to the application event handler list that 
  338.     *   the AppleEvent manager maintains.  So, whenever an AppleEvent happens
  339.     *   and we call AEProcessEvent, the AppleEvent manager will check our
  340.     *   list of handlers and dispatch to it if there is one.
  341.     */
  342.     if (gHasAppleEvents) {
  343.         register qq;
  344.         for (qq = 0; qq < ((sizeof(HandlersToInstall) / sizeof(AEinstalls))); qq++) {
  345.             aevtErr = AEInstallEventHandler(HandlersToInstall[qq].theClass, HandlersToInstall[qq].theEvent,
  346.                                             HandlersToInstall[qq].theProc, 0, false);
  347.             if (aevtErr) {
  348.                 ExitToShell();                              /* just fail, baby */
  349.             }
  350.         }
  351.     } else {
  352.         ExitToShell();
  353.     }
  354. }
  355.  
  356. /* end InitAEStuff */
  357. /* I'm not doing error handling in this sample for clarities sake, you should. Hah, */
  358. /* easy for me to say, huh? */
  359. void DoHighLevel(EventRecord *AERecord)
  360. {
  361.     
  362.     AEProcessAppleEvent(AERecord);
  363.     
  364. }
  365.  
  366. /* end DoHighLevel */
  367.  
  368. /* This is the standard Open Application event.  */
  369. pascal OSErr AEOpenHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  370. {
  371. #pragma unused (messagein,reply,refIn)
  372.     /* we of course don't do anything here in this simple app */
  373.     /* except open our window */
  374.     myWindow = GetNewWindow(128, nil, (WindowPtr)-1);
  375.     return(noErr);
  376. }
  377.  
  378. /* end AEOpenHandler */
  379.  
  380. /* Open Doc, opens our documents.  Remember, this can happen at application start AND */
  381. /* anytime else.  If your app is up and running and the user goes to the desktop, hilites one */
  382. /* of your files, and double-clicks or selects Open from the finder File menu this event */
  383. /* handler will get called. Which means you don't do any initialization of globals here, or */
  384. /* anything else except open the doc.  */
  385. /* SO-- Do NOT assume that you are at app start time in this */
  386. /* routine, or bad things will surely happen to you. */
  387.  
  388. pascal OSErr AEOpenDocHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  389. {
  390. #pragma unused (messagein,refIn,reply)
  391.     /* we of course don't do anything here */
  392.     return(errAEEventNotHandled);                           /* we have no docs, so no odoc events should come to us */
  393. }
  394.  
  395. pascal OSErr AEPrintHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  396. {                                                           /* no printing handler in yet, so we'll ignore this */
  397.     /* the operation is functionally identical to the ODOC event, with the additon */
  398.     /* of calling your print routine.  */
  399. #pragma unused (messagein,refIn,reply)
  400.     /* we of course don't do anything here */
  401.     return(errAEEventNotHandled);                           /* we have no docs, so no pdoc events should come to us */
  402. }
  403.  
  404. /* Standard Quit event handler, to handle a Quit event from the Finder, for example.  */
  405. /* ••••• DO NOT CALL EXITTOSHELL HERE ••••• or you will never have a happy life.  */
  406. pascal OSErr AEQuitHandler(AppleEvent *messagein, AppleEvent *reply, long refIn)
  407. {
  408. #pragma unused (messagein,refIn,reply)
  409.     
  410.     /* prepQuit sets the Stop flag for us.  It does _NOT_ quit, you */
  411.     /* should NEVER quit from an AppleEvent handler.  Calling */
  412.     /* ExitToShell here would blow things up */
  413.     gQuit = true;
  414.     return(noErr);
  415. }
  416.  
  417.  
  418. /* This is my sample help dialog.  Does not do anything, expand as you need */
  419. void SampleHelpDialog(void)
  420. {
  421.     DialogPtr tdial = GetNewDialog(kSampHelp, nil, (WindowPtr)-1);
  422.     short itemhit = 0;
  423.     while (itemhit != 1) {
  424.         ModalDialog((ModalFilterProcPtr)nil, &itemhit);
  425.     }
  426.     DisposDialog(tdial);
  427. }
  428.  
  429.  
  430. /* This is the killer code.  It finds and kills every other  */
  431. /* application on your machine. */
  432. void KillEveryBody(void)
  433. {
  434.     ProcessSerialNumber myProc, processSN;
  435.     ProcessSerialNumber finderPSN;
  436.     ProcessInfoRec infoRec;
  437.     Str31 processName;
  438.     FSSpec procSpec;
  439.     
  440.     OSErr myErr = noErr;
  441.     OSErr otherError;
  442.     AppleEvent theEvent;
  443.     AEDesc theAddress;
  444.     Boolean ourFlag, notFinder;
  445.     Boolean finderFound = false;
  446.     GetCurrentProcess(&myProc);
  447.     /* Preset the PSN to no PSN, see IM VI, the Process Manager */
  448.     processSN.lowLongOfPSN = kNoProcess;
  449.     processSN.highLongOfPSN = kNoProcess;
  450.     finderPSN.lowLongOfPSN = nil;
  451.     finderPSN.highLongOfPSN = nil;
  452.     
  453.     do {
  454.         myErr = GetNextProcess(&processSN);
  455.         SameProcess(&myProc, &processSN, &ourFlag);
  456.         if (!ourFlag && !finderFound) {
  457.             /* see if it's the Finder, we have to kill the finder LAST */
  458.             /* or else non-sys 7 apps won't get killed */
  459.             /* since the Finder must be there to convert the AppleEvent to Puppet Strings */
  460.             /* if the app is not APpleEvent aware */
  461.             infoRec.processInfoLength = sizeof(ProcessInfoRec);
  462.             infoRec.processName = &processName;
  463.             infoRec.processAppSpec = &procSpec;
  464.             GetProcessInformation(&processSN, &infoRec);
  465.             if (infoRec.processSignature == 'MACS' && infoRec.processType == 'FNDR') {
  466.                 /* save this number for later  */
  467.                 finderPSN = processSN;
  468.                 notFinder = false;
  469.             } else {
  470.                 notFinder = true;
  471.                 finderFound = true;
  472.             }
  473.         }
  474.         if (!myErr && !ourFlag && notFinder) {
  475.             otherError = AECreateDesc(typeProcessSerialNumber, (Ptr)&processSN, sizeof(processSN), &theAddress);
  476.             if (!otherError)
  477.                 otherError = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &theAddress, kAutoGenerateReturnID,
  478.                                                 kAnyTransactionID, &theEvent);
  479.             if (!otherError)
  480.                 AEDisposeDesc(&theAddress);
  481.             /* Again, the Finder will convert the AppleEvent to puppetstrings if */
  482.             /* the application is a System 6 or non-AE aware app.  This ONLY  */
  483.             /* happens for the 4 required (oapp,odoc,pdoc, and quit) AppleEvents  */
  484.             /* and ONLY if you use the PSN for the address */
  485.             if (!otherError)
  486.                 AESend(&theEvent, nil, kAENoReply + kAEAlwaysInteract + kAECanSwitchLayer, kAENormalPriority, kAEDefaultTimeout,
  487.                        nil, nil);
  488.             AEDisposeDesc(&theEvent);
  489.         }
  490.     }
  491.             while (!myErr);
  492.     /* Now, if the finder was running, it's safe to kill it */
  493.     if (finderPSN.lowLongOfPSN || finderPSN.highLongOfPSN) {
  494.         otherError = AECreateDesc(typeProcessSerialNumber, (Ptr)&finderPSN, sizeof(processSN), &theAddress);
  495.         if (!otherError)
  496.             otherError = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &theAddress, kAutoGenerateReturnID,
  497.                                             kAnyTransactionID, &theEvent);
  498.         if (!otherError)
  499.             AEDisposeDesc(&theAddress);
  500.         if (!otherError)
  501.             AESend(&theEvent, nil, kAENoReply + kAEAlwaysInteract + kAECanSwitchLayer, kAENormalPriority, kAEDefaultTimeout, nil,
  502.                    nil);
  503.         AEDisposeDesc(&theEvent);
  504.     }
  505. }
  506.  
  507.  
  508. #pragma segment Initialize
  509. void InitalizeApp(void)
  510. {
  511.     MenuHandle helpHandle;
  512.     StringHandle helpString;
  513.     short count;
  514.     long vers;
  515.     MaxApplZone();
  516.     InitGraf((Ptr)&qd.thePort);
  517.     InitFonts();
  518.     InitWindows();
  519.     InitMenus();
  520.     TEInit();
  521.     InitDialogs(nil);
  522.     InitCursor();
  523.     /* Check system version */
  524.     Gestalt(gestaltSystemVersion, &vers);
  525.     vers = (vers >> 8) & 0xf;                               /* shift result over and mask out major version number */
  526.     if (vers < 7) {
  527.         StopAlert(kBadSystem, nil);
  528.         ExitToShell();
  529.     }
  530.     InitAEStuff();
  531.     /* set up my menu junk */
  532.     gMymenu = GetNewMBar(kMBarID);
  533.     SetMenuBar(gMymenu);
  534.     gAppleMenuHandle = GetMHandle(kAppleMenu);
  535.     gFileMenuHandle = GetMHandle(kFileMenu);
  536.     gEditMenuHandle = GetMHandle(kEditMenu);
  537.     gToolMenuHandle = GetMHandle(kToolsMenu);
  538.     AddResMenu(gAppleMenuHandle, 'DRVR');
  539.     /* now install my Help menu item in the Help Manager's menu */
  540.     HMGetHelpMenuHandle(&helpHandle);                       /* Get the Hlpe menu handle */
  541.     count = CountMItems(helpHandle);                        /* How many items are there? */
  542.     helpString = GetString(kHelpString);                    /* get my help string */
  543.     DetachResource(helpString);                             /* detach it */
  544.     HNoPurge(helpString);
  545.     MoveHHi((Handle)helpString);
  546.     HLock((Handle)helpString);
  547.     InsMenuItem(helpHandle, (Ptr)*helpString, count + 1);       /* insert my item in the Help menu */
  548.     gHelpItem = CountMItems(helpHandle);                    /* The number of the item */
  549.     
  550.     DrawMenuBar();
  551.     GetCurrentProcess(&gOurSN);                             /* Get our process serial number for later use, if needed */
  552.     
  553. }
  554.